import path from 'path';

import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import * as IWebpackChainConfig from 'webpack-chain';

const isProd = process.env.NODE_ENV === 'production';

function getModulePackageName(module: { context: string }) {
  if (!module.context) return null;

  const nodeModulesPath = path.join(__dirname, '../node_modules/');
  if (module.context.substring(0, nodeModulesPath.length) !== nodeModulesPath) {
    return null;
  }

  const moduleRelativePath = module.context.substring(nodeModulesPath.length);
  const [moduleDirName] = moduleRelativePath.split(path.sep);
  let packageName: string | null = moduleDirName;
  // handle tree shaking
  if (packageName && packageName.match('^_')) {
    // eslint-disable-next-line prefer-destructuring
    packageName = packageName.match(/^_(@?[^@]+)/)![1];
  }
  return packageName;
}

export const webpackPlugin = (config: IWebpackChainConfig) => {
  config
    .when(isProd, config => {
      config.module
        .rule('css')
        .test(/\.css$/)
        .use('style')
        .loader(MiniCssExtractPlugin.loader);
    })
    .when(!isProd, config => {
      config.module
        .rule('css')
        .test(/\.css$/)
        .use('style-loader')
        .loader('style-loader');
    });

  config.module
    .rule('css')
    .test(/\.css$/)
    .use('css')
    .loader('css-loader')
    .options({
      modules: true,
    })
    .end()
    .use('postcss-loader')
    .loader('postcss-loader');

  // optimize chunks
  config.optimization
    // share the same chunks across different modules
    //.runtimeChunk(false)
    .splitChunks({
      chunks: 'all',
      automaticNameDelimiter: '.',
      name: true,
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 10,
      maxInitialRequests: 5,
      cacheGroups: {
        vendors: {
          name: 'vendors',
          chunks: 'all',
          test: /[\\/]node_modules[\\/](react|react-dom|react-router|react-router-dom|lodash|lodash-decorators|redux-saga|re-select|dva|moment)[\\/]/,
          priority: -10,
        },
        antdesigns: {
          name: 'antdesigns',
          chunks: 'all',
          test: /[\\/]node_modules[\\/](@ant-design|antd)[\\/]/,
          priority: -11,
        },
        devextreme: {
          name: 'devextreme',
          chunks: 'all',
          test: /[\\/]node_modules[\\/](devextreme|devextreme-react)[\\/]/,
          priority: -12,
        },
        bryntum: {
          name: 'bryntum',
          chunks: 'all',
          test: /[\\/]node_modules[\\/](bryntum-gantt|bryntum-react-shared|bryntum-resources)[\\/]/,
          priority: -13,
        },
        default: {
          name: 'defaultgroup',
          minChunks: 1,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    });
};
